package comp
{
	use namespace comp_layout;
	
	import comp.style.css.CssAchieve;
	import comp.style.css.MergeLayout;
	import comp.style.theme.ScrollBarTheme;
	
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.events.TextEvent;
	import flash.geom.Rectangle;
	import flash.text.StyleSheet;
	import flash.text.TextField;
	import flash.text.TextFormat;

	/**
	 * 富文本控件，支持表情。
	 * 自动滚动条
	 * 支持html
	 * 文本样式:textAlign,color,fontFamily,fontSize;
	 * 滚动条显示控制overflow
	 */
	public class TextArea extends UIComponent
	{
		include "style/PaddingStyles"//内边距离
		include "style/TextStyles";//包含样式
		include "style/SkinStyle" //皮肤属性

		public function TextArea()
		{
			super();
			this.addEventListener(MouseEvent.MOUSE_WHEEL,onWheelHandler);
			this._themeName="comp::TextArea";
		}
		//*********************
		//样式
		//*********************
		private var _overflow:String;//="visible";	//visible,hidden,scroll,auto	
		private var _maxWidth:Number;//=0;//最大宽度
		private var _maxLines:uint;//=40;//显示最大行数
		private var _styleSheet:StyleSheet;
		
		/**
		 * 根据ubb获取图片
		 * function(ubb:String):DisplayObject
		 */
		public function get getImgFunction():Function
		{
			return _getImgFunction;
		}

		/**
		 * @private
		 */
		public function set getImgFunction(value:Function):void
		{
			_getImgFunction = value;
		}

		public function get maxLines():uint
		{
			return _maxLines;
		}

		public function set maxLines(value:uint):void
		{
			_maxLines = value;
		}
		
		public function get maxWidth():Number
		{
			return _maxWidth;
		}
		
		public function set maxWidth(value:Number):void
		{
			_maxWidth=value;
		}

		override public function set visible(value:Boolean):void
		{
			super.visible=value;
			if(_scrollbar)
				_scrollbar.visible=value;
		}
		
		public function get overflow():String
		{
			return _overflow;
		}
		/**
		 * 滚动条显示条件
		 * visible 默认值。内容不会被修剪，会呈现在元素框之外。 
		 * hidden 内容会被修剪，并且其余内容是不可见的 不显示滚动条。 
		 * auto 如果内容被修剪，则浏览器会显示滚动条以便查看其余的内容。 
		 */
		public function set overflow(value:String):void
		{
			_overflow = value;
		}

		//***********
		//属性
		//***********
		public function get linkClick():Function
		{
			return _linkClick;
		}

		/**
		 * 文本的超级链接点击事件
		 */
		public function set linkClick(value:Function):void
		{
			_linkClick = value;
		}

		public function get editInfo():Object
		{
			return _editInfo;
		}

//		public function get type():String
//		{
//			return _type;
//		}
//
//		public function set type(value:String):void
//		{
//			_type = value;
//		}

		public function get textField():TextField
		{
			return _textField;
		}
		
		public function set textField(value:TextField):void
		{
			_textField = value;
		}

		public function get resource():Array
		{
			return _resource;
		}

		public function set resource(value:Array):void
		{
			_resource = value;
		}

		public function get htmlText():String
		{
			return _htmlText;
		}
		

		public function set htmlText(value:String):void
		{
			_htmlText = value;
			if(initialized)
			{
				commitProperties();
				onSizeChangeHandle();
			}
		}

		public function get pattern():RegExp
		{
			return _pattern;
		}

		public function set pattern(value:RegExp):void
		{
			_pattern = value;
		}

		public function get text():String
		{
			return _text;
		}

		public function get textWidth():Number
		{
			if(_textField!=null)
				return _textField.textWidth;
			else
				return 0;
		}
		
		public function get textHeight():Number
		{
			if(_textField!=null)
				return _textField.textHeight;
			else
				return 0;
		}
		
		/**
		 * 设置记录用户操作信息
		 */
		public function setEditInfo():void
		{
			_editInfo={beginIndex:_textField.caretIndex,len:_textField.length-_textField.caretIndex};
		}
		
		//**********
		//公共函数
		//**********
		/**
		 * 追加html内容
		 */
		public function appendHtmlText(content:String):void
		{
			_htmlText+=	content;	
			if(initialized)
			{
				textField.htmlText=_htmlText;
				autoWith();

				_testResult.length=0;
				clearResource();				
				replaceFace();
				onSizeChangeHandle();
			}
		}
		
		/**
		 * 清除图片等显示资源
		 */
		public function clearResource():void
		{
			for(var i:uint=this.numChildren;i>1;i--)
			{
				var d:DisplayObject=this.getChildAt(1);
				if(d==this._textField || d==this.currentSkin)
					continue;
				
				this.removeChild(d);
			}
		}
		
		/**
		 * 大小改变的时候外部调用判断是否显示滚动条
		 */
		public function onSizeChangeHandle():void
		{
			calculateMaxSize();
			var ovf:String=getStyleDefault("overflow","auto");
			if(ovf=="hidden" ||ovf=="visible") //如果是不显示
				return;

			scrollRect=new Rectangle(0,0,width,height);//如果指定了宽度
			if(height<_maxHeight)
				showScroll();
			else
				hideScroll();

		}
		
		/**
		 * 滚动到底部
		 */
		public function scrollToBottom():void
		{
			if(this._scrollbar!=null)
				this._scrollbar.scroll(this._scrollbar.height);
			else
				_textField.scrollV=_textField.numLines;
		}
		
		/**
		 * 重新设置大小
		 */
		public function resize(width:Number,height:Number):void
		{
			this.width=width;
			this.height=height;
			_textField.width=width;
			_textField.height=height;
			onSizeChangeHandle();
		}
		
		//***********
		//重写父类
		//***********
		override protected function createChildren():void
		{
			_textField=new TextField;
			_textField.wordWrap=true;
			_textField.multiline=true;
//			_textField.autoSize="left";
			_textField.addEventListener(TextEvent.TEXT_INPUT,onTextInput);
			_textField.addEventListener(Event.CHANGE,onChange);
			_textField.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
			_textField.addEventListener(TextEvent.LINK,onlinkClick);			
			addChild(_textField);
		}
		
		override protected function commitProperties():void
		{
			if(_textField)
			{
				_textField.htmlText=_htmlText;
				
				autoWith();
				
				_testResult.length=0;
				this.scrollRect=null;
				clearResource();				
				replaceFace();
			}
		}

		
		/**
		 * 计算大小，判断是否显示滚动条
		 */
		override protected function calculateSize():void
		{
			var ovf:String=getStyleDefault("overflow","auto");
			if(ovf=="visible" ||ovf=="auto")//完全可见不显示滚动条
			{
				if(width==0 )
					width=spriteWidth;
				if(height==0)
					height=spriteHeight;
			}
			
			onSizeChangeHandle();	
		}
		override protected function merge():void
		{
			MergeLayout.labelLayout(_textField,this);
			CssAchieve.mergeTemplate(this);
			CssAchieve.mergeBackGrounde(this);	
		}
		
		override protected function commitStyles():void
		{
			CssAchieve.mergeTextField(_textField,this);
			_textField.autoSize=getStyle("textAlign");		
			if(!_autoW)
				_textField.width=this.width;
					
		}
		
		/**
		 * 计算最大高度
		 * 用于判断是否显示滚动条
		 */
		protected function calculateMaxSize():void
		{
			var tMax:Number=0;
			for(var i:uint=0;i<this.numChildren;i++)
			{
				var s:Object=this.getChildAt(i);
				var cheight:Number;
				if(s is UIComponent)
				{
					if(s.visible==true) 
						cheight=s.y+(s.maxHeight==0?s.spriteHeight:s.maxHeight);
				}
				else
					cheight=s.y+s.height;
				
				if(tMax<=cheight)
					tMax=cheight;
			}
			_maxHeight=tMax;
		}
		
		protected function autoWith():void
		{
			var maxw:Number=getStyle("maxWidth");
			if(maxw>0)
			{
				_textField.width=maxw;
				var w:Number=_textField.textWidth+6;
				if(_textField.width>=w)
					_textField.width=w;
				
				this.width=_textField.width;
			}
		}
		/**
		 * 当有文本输入的时候
		 */
		protected function onTextInput(e:TextEvent):void
		{
//			this.appendHtmlText(e);
		}
		
		protected function onlinkClick(e:TextEvent):void
		{
			if(this._linkClick!=null)
				_linkClick(e);
		}
		
		protected function onKeyDown(e:KeyboardEvent):void
		{
			_editInfo={};
		}
		
		protected function onChange(e:Event):void
		{

			trace(_textField.selectionBeginIndex);
			trace(_textField.selectionEndIndex);
		}
		
		///////////////////////
		//表情相关操作
		////////////////////////
		
		/**
		 * 表情替换
		 */
		protected function replaceFace():void
		{
			this._testResult=searchFacePos(_textField.text,_textField.htmlText);
			this.addFace();
		}
		/**
		 * 寻找表情位置
		 * str为textField.text属性
		 */
		private function searchFacePos(str:String,htm:String):Array
		{
//			str=str.replace(" ","");
			var l:uint=str.length;
			var ar:*;//结果
			var result:Array=new Array;			
			var dis:DisplayObject;//表情显示对像
			var w:Number,h:Number,size:int,tmp:String,font:String;//
			ar=_pattern.exec(str);
			var html:String=htm;

			//寻找要查找内容的值和位置放入_testResult
			var j:int=0;
			for(var i:uint=0;i<=l;i=_pattern.lastIndex)
			{
				if(ar)
				{
					if(_getImgFunction!=null)
						dis=_getImgFunction(ar[0]);
					else
						dis=getDisplay(ar[0]);
					if(dis)
					{
						w=dis.width;
						h=dis.height;
					}

					size=(w/h);
					if(size<1)
						size=1;
					
					tmp="";
					font="<font id='"+j+"' size='"+h+"'>";
					for(var j:int=0;j<size;j++)
					{
						font+="   ";
						tmp+="   ";
					}
					font+="</font>";
					str=str.replace(ar[0],tmp);
					l=str.length;
					result.push({"id":j,"value":ar[0],"index":ar["index"],"display":dis,"width":w,"height":h,"size":size});//值,索引，位置,图片
					j++;
					html=html.replace(ar[0],font);
					_pattern.lastIndex=0;
					ar=_pattern.exec(str);
				}
				else
					break;
			}
			
			_textField.htmlText=html;
			return result;
		}
		
		
		/**
		 * 添加表情
		 */
		private function addFace():void
		{
			var r:Rectangle;//位置
			var mv:DisplayObject;//显示对像
			var lineNum:Number;//行

			var bindex:int=0,lastIndex:int=0;
			var fs:int=this.getStyle("fontSize");
			//换表情
			for(var i:uint=0;i<_testResult.length;i++)
			{
				var obj:Object=_testResult[i];
				if(obj.display)
				{
					var bindex:int=obj.index<_textField.length?obj.index:_textField.length-1;
					var h:Number=_textField.height;//);//这个trace不能去掉？
					r=_textField.getCharBoundaries(bindex);
					var stri:String=_textField.text.charAt(bindex);
					if(r)
					{
						obj.display.x=r.x;
						var dy:Number=r.height-obj.display.height;;
						obj.display.y=r.y+dy-4;
						if(obj.display.parent==null)
						addChild(obj.display);
					}
				}
			}
		}
	
		/**
		 * 得到显示的图片
		 */
		protected function getDisplay(ubb:String):DisplayObject
		{
			var fi:uint=0;//表情索引
			var mv:DisplayObject;
			fi=uint(ubb.substr(1,ubb.length-2));

			if(fi<_resource.length)
				mv=new _resource[fi];
			return mv;
		}

		/**
		 * 滚轮事件
		 */
		protected function onWheelHandler(e:MouseEvent):void
		{
			if(_scrollbar)
				_scrollbar.scroll(-e.delta*2);
		}
		
		/**
		 * 创建滚动条
		 */
		protected function showScroll():void
		{
			if(!_scrollbar && scrollRect!=null)
			{
				_scrollbar=new ScrollBar;
				_scrollbar.height=scrollRect.height;
				_scrollbar.maxHeight=_maxHeight;
				_scrollbar.visible=false;
				_scrollbar.tag=this;
				_scrollbar.className=this.getStyle("scrollBarClass");
				_scrollbar.onScroll=function(n:Number):void{
					if(_scrollbar.visible==false)
						return;
					
					var r:Rectangle=this.tag.scrollRect;
					if(r)
					{
						r.y=n;
						var r1:Rectangle=r;
						this.tag.scrollRect=r1;
					}
					
				}
				_scrollbar.initialize();
				addScroll();
				caleScrollPos();
			}
			
			if(_scrollbar)
			{
				if(!_scrollbar.parent)
				{
					addScroll();
				}
				caleScrollPos();
				_scrollbar.visible=this.getStyle("visible");
				_scrollbar.height=scrollRect.height;
				_scrollbar.maxHeight=_maxHeight;
				_scrollbar.onSizeChange();
			}
			
		}
		
		/**
		 * 添加滚动条
		 */
		protected function addScroll():void
		{
			if(parent)					
			{
				var index:uint=parent.getChildIndex(this);
				index=index+1;		
				parent.addChildAt(_scrollbar,index);
			}
		}
		
		protected function caleScrollPos():void
		{
			if(_scrollbar.parent)
			{
				var p:UIComponent=parent as UIComponent;
			}
			
			if(p)//如果是自定义控件		
			{
				var pl:*=p.getStyle("paddingLeft");
				var pt:*=p.getStyle("paddingTop");
				if(!pl)pl=0;
				if(!pt)pt=0;
				_scrollbar.x=x+width-pl;
				_scrollbar.y=y-pt;
			}
			else
			{
				_scrollbar.x=x+width;
				_scrollbar.y=y;
			}
			
		}
		
		/**
		 * 隐藏滚动条
		 */
		protected function hideScroll():void
		{
			if(_scrollbar)
				_scrollbar.visible=false;
		}

		/**
		 * 图片样式
		 */
		public function get styleSheet():StyleSheet
		{
			return _styleSheet;
		}
		
		public function set styleSheet(value:StyleSheet):void
		{
			_styleSheet = value;
		}
		
		//private
		//***********
		//私成成员
		//***********

//		private var _type:String;//
		private var _textField:TextField;
		private var _htmlText:String="";//html文本
		private var _text:String="";//富文本
		private var _pattern:RegExp=/\[(\w|\d){1,3}\]/mgi;///\(\d{2}\)/mgi;//正规表达式
		private var _testResult:Array=[];//匹配结果数组
		private var _resource:Array=[];//资源
		private var _editInfo:Object;//记录用户的操作信息，当前操作的光标开始位置和操作内容的长度
		private var _linkClick:Function;

		private var _getImgFunction:Function;//
		/**
		 * 滚动条样式
		 */
		public function get scrollBarClass():String
		{
			return _scrollBarClass;
		}

		/**
		 * @private
		 */
		public function set scrollBarClass(value:String):void
		{
			_scrollBarClass = value;
		}

		private var _scrollBarClass:String;//滚动条样式

		private var _scrollbar:ScrollBar;//滚动条
	}
}